/*
 * Copyright (c) 2025, Mediatek Inc. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef MT_SPM_HWREQ_H
#define MT_SPM_HWREQ_H

#include <drivers/spm/mt_spm_resource_req.h>
#include <mt_spm_common_v1.h>

/* ddren, apsrc and emi resource have become hw resource_req.
 * So we don't need to use HW CG for request resource.
 */
#define SPM_HWCG_DDREN_PWR_MB	(0)
#define SPM_HWCG_DDREN_PWR_MSB_MB	(0)
#define SPM_HWCG_DDREN_MODULE_BUSY_MB	(0)

/* VRF18 */
#define SPM_HWCG_VRF18_PWR_MB                                          \
	(BIT(HWCG_PWR_ISP_IMG1) | BIT(HWCG_PWR_ISP_IMG2) |                 \
	 BIT(HWCG_PWR_ISP_IPE) | BIT(HWCG_PWR_VDE0) | BIT(HWCG_PWR_VEN0) | \
	 BIT(HWCG_PWR_CAM_MAIN) | BIT(HWCG_PWR_CAM_SUBA) |                 \
	 BIT(HWCG_PWR_CAM_SUBB) | BIT(HWCG_PWR_CAM_VCORE) |                \
	 BIT(HWCG_PWR_MDP0) | BIT(HWCG_PWR_MM_INFRA))

#define SPM_HWCG_VRF18_PWR_MSB_MB                                       \
	(BIT(HWCG_PWR_DP_TX) | BIT(HWCG_PWR_EMI0) | BIT(HWCG_PWR_CSI_RX) |  \
	 BIT(HWCG_PWR_SSRSYS) | BIT(HWCG_PWR_SSPM) | BIT(HWCG_PWR_EDP_TX) | \
	 BIT(HWCG_PWR_PCIE) | BIT(HWCG_PWR_PCIE_PHY))

#define SPM_HWCG_VRF18_MODULE_BUSY_MB	(0)

/* INFRA */
#define SPM_HWCG_INFRA_PWR_MB	(SPM_HWCG_VRF18_PWR_MB)
#define SPM_HWCG_INFRA_PWR_MSB_MB	(SPM_HWCG_VRF18_PWR_MSB_MB)
#define SPM_HWCG_INFRA_MODULE_BUSY_MB	(0)

/* PMIC */
#define SPM_HWCG_PMIC_PWR_MB	(SPM_HWCG_INFRA_PWR_MB)

#define SPM_HWCG_PMIC_PWR_MSB_MB	(SPM_HWCG_INFRA_PWR_MSB_MB)
#define SPM_HWCG_PMIC_MODULE_BUSY_MB	(0)

/* F26M */
#define SPM_HWCG_F26M_PWR_MB \
	((SPM_HWCG_PMIC_PWR_MB) | BIT(HWCG_PWR_AUDIO))

#define SPM_HWCG_F26M_PWR_MSB_MB (SPM_HWCG_PMIC_PWR_MSB_MB)

#define SPM_HWCG_F26M_MODULE_BUSY_MB                    \
	(BIT(HWCG_MODULE_MMPLL) | BIT(HWCG_MODULE_UFSPLL) | \
	 BIT(HWCG_MODULE_MSDCPLL) | BIT(HWCG_MODULE_UNIVPLL))

/* VCORE */
#define SPM_HWCG_VCORE_PWR_MB \
	((SPM_HWCG_F26M_PWR_MB) | BIT(HWCG_PWR_UFS0))

#define SPM_HWCG_VCORE_PWR_MSB_MB (SPM_HWCG_F26M_PWR_MSB_MB)
#define SPM_HWCG_VCORE_MODULE_BUSY_MB (SPM_HWCG_F26M_MODULE_BUSY_MB)

#define INFRA_SW_CG_MB	(0)

#define PERI_REQ_EN_MASK 0x3FFFF

/* Resource requirement which HW CG support */
enum {
	HWCG_DDREN = 0,
	HWCG_VRF18,
	HWCG_INFRA,
	HWCG_F26M,
	HWCG_PMIC,
	HWCG_VCORE,
	HWCG_MAX
};

enum spm_pwr_status {
	HWCG_PWR_MD1 = 0,
	HWCG_PWR_CONN,
	HWCG_PWR_IFR,
	HWCG_PWR_PERI,
	HWCG_PWR_UFS0,
	HWCG_PWR_UFS0_PHY,
	HWCG_PWR_AUDIO,
	HWCG_PWR_ADSP_TOP,
	HWCG_PWR_ADSP_INFRA = 8,
	HWCG_PWR_ADSP_AO,
	HWCG_PWR_ISP_IMG1,
	HWCG_PWR_ISP_IMG2,
	HWCG_PWR_ISP_IPE,
	HWCG_PWR_ISP_VCORE,
	HWCG_PWR_VDE0,
	HWCG_PWR_VDE1,
	HWCG_PWR_VEN0 = 16,
	HWCG_PWR_VEN1,
	HWCG_PWR_CAM_MAIN,
	HWCG_PWR_CAM_MRAW,
	HWCG_PWR_CAM_SUBA,
	HWCG_PWR_CAM_SUBB,
	HWCG_PWR_CAM_SUBC,
	HWCG_PWR_CAM_VCORE,
	HWCG_PWR_CAM_CCU = 24,
	HWCG_PWR_CAM_CCU_AO,
	HWCG_PWR_MDP0,
	HWCG_PWR_MDP1,
	HWCG_PWR_DIS0,
	HWCG_PWR_DIS1,
	HWCG_PWR_MM_INFRA,
	HWCG_PWR_MM_PROC,
	HWCG_PWR_MAX
};

enum spm_pwr_msb_status {
	HWCG_PWR_DP_TX = 0,
	HWCG_PWR_SCP_CORE,
	HWCG_PWR_SCP_PERI,
	HWCG_PWR_DPM0,
	HWCG_PWR_DPM1,
	HWCG_PWR_EMI0,
	HWCG_PWR_EMI1,
	HWCG_PWR_CSI_RX,
	HWCG_PWR_SSRSYS = 8,
	HWCG_PWR_SSPM,
	HWCG_PWR_SSUSB,
	HWCG_PWR_SSUSB_PHY,
	HWCG_PWR_EDP_TX,
	HWCG_PWR_PCIE,
	HWCG_PWR_PCIE_PHY,
	HWCG_PWR_MSB_EMPTY_BIT15,
	HWCG_PWR_MSB_EMPTY_BIT16 = 16,
	HWCG_PWR_MSB_EMPTY_BIT17,
	HWCG_PWR_MSB_EMPTY_BIT18,
	HWCG_PWR_MSB_EMPTY_BIT19,
	HWCG_PWR_MSB_EMPTY_BIT20,
	HWCG_PWR_MSB_EMPTY_BIT21,
	HWCG_PWR_MSB_EMPTY_BIT22,
	HWCG_PWR_MSB_EMPTY_BIT23,
	HWCG_PWR_MSB_EMPTY_BIT24 = 24,
	HWCG_PWR_MSB_EMPTY_BIT25,
	HWCG_PWR_MSB_EMPTY_BIT26,
	HWCG_PWR_MSB_EMPTY_BIT27,
	HWCG_PWR_MSB_EMPTY_BIT28,
	HWCG_PWR_MSB_EMPTY_BIT29,
	HWCG_PWR_MSB_EMPTY_BIT30,
	HWCG_PWR_MSB_EMPTY_BIT31,
	HWCG_PWR_MSB_MAX
};

enum spm_hwcg_module_busy {
	HWCG_MODULE_AUDIO = 0,
	HWCG_MODULE_MMPLL,
	HWCG_MODULE_UFSPLL,
	HWCG_MODULE_MSDCPLL,
	HWCG_MODULE_UNIVPLL,
	HWCG_MODULE_MAX
};

/* Resource requirement which PERI REQ support */
enum spm_peri_req {
	PERI_REQ_F26M = 0,
	PERI_REQ_INFRA,
	PERI_REQ_SYSPLL,
	PERI_REQ_APSRC,
	PERI_REQ_DDREN,
	PERI_REQ_EMI,
	PERI_REQ_PMIC,
	PERI_REQ_MAX
};

enum spm_peri_req_en {
	PERI_REQ_EN_DMA = 1,
	PERI_REQ_EN_UART0,
	PERI_REQ_EN_UART1,
	PERI_REQ_EN_UART2,
	PERI_REQ_EN_UART3,
	PERI_REQ_EN_PWM = 6,
	PERI_REQ_EN_SPI0,
	PERI_REQ_EN_SPI1,
	PERI_REQ_EN_SPI2,
	PERI_REQ_EN_SPI3 = 10,
	PERI_REQ_EN_SPI4,
	PERI_REQ_EN_SPI5,
	PERI_REQ_EN_I2C,
	PERI_REQ_EN_MSDC0,
	PERI_REQ_EN_MSDC1 = 15,
	PERI_REQ_EN_MSDC2,
	PERI_REQ_EN_SSUSB0 = 17,
	PERI_REQ_EN_SSUSB1,
	PERI_REQ_EN_SSUSB2,
	PERI_REQ_EN_SSUSB3,
	PERI_REQ_EN_SSUSB4,
	PERI_REQ_EN_PEXTP,
	PERI_REQ_EN_AFE = 23,
	PERI_REQ_EN_MAX
};

#define INFRA_AO_OFFSET(offset) (INFRACFG_AO_BASE + offset)
#define INFRA_SW_CG_0_MASK INFRA_AO_OFFSET(0x060)
#define INFRA_SW_CG_1_MASK INFRA_AO_OFFSET(0x064)
#define INFRA_SW_CG_2_MASK INFRA_AO_OFFSET(0x068)
#define INFRA_SW_CG_3_MASK INFRA_AO_OFFSET(0x0CC)
#define INFRA_SW_CG_4_MASK INFRA_AO_OFFSET(0x0EC)

#define REG_PERI_REQ_EN(N) (PERICFG_AO_BASE + 0x050 + 0x4 * N)
#define REG_PERI_REQ_STA(N) (PERICFG_AO_BASE + 0x06C + 0x4 * N)

static inline uint32_t spm_hwcg_num(void)
{
	return HWCG_MAX;
}

static inline uint32_t spm_peri_req_num(void)
{
	return PERI_REQ_MAX;
}

#endif
